package com.lincoln.redis.server.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.lincoln.redis.server.bean.BaseEntity;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;

import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * 基础Service
 *
 * @param <T>
 * @author lincoln
 */
@Component
public class BaseServiceImpl<T extends BaseEntity> {
    protected Jedis jedis;

    /**
     * 对象key生成策略
     *
     * @param t
     * @return
     */
    public String exGenerateKey(T t) throws Exception {
        if(t == null){
            return exTableKeyHeader() + ".*";
        }
        return exTableKeyHeader() + "." + t.getId() == null ? "*" : String.valueOf(t.getId());
    }

    /**
     * 对象key生成策略
     *
     * @param id
     * @return
     */
    public String exGenerateKeyById(Long id) throws Exception {
        T t = ((Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]).newInstance();
        t.setId(id);
        return exGenerateKey(t);
    }

    /**
     * 表前缀
     *
     * @return
     */
    protected String exTableKeyHeader() {
        return null;
    }

    /**
     * 生成主键
     *
     * @return
     */
    protected long generateId() {
        return jedis.incrBy(exTableKeyHeader() + "Id", 1);
    }

    public boolean save(T t) {
        if (t.getId() == null) {
            t.setId(generateId());
        }
        if (t.getCreateTime() == null) {
            t.setCreateTime(new Date());
        }
        if (t.getUpdateTime() == null) {
            t.setUpdateTime(new Date());
        }
        try {
            jedis.set(exGenerateKey(t), JSONObject.toJSONString(t));
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    /**
     * 删除
     *
     * @param t
     * @return
     */
    public boolean delete(T t) {
        Set<String> keys = null;
        try {
            keys = jedis.keys(exGenerateKey(t));
        } catch (Exception e) {
            return false;
        }
        if (keys == null || keys.size() <= 0) {
            return false;
        }
        for (String key : keys) {
            jedis.del(key);
        }
        return true;
    }

    /**
     * 删除
     *
     * @param id
     * @return
     */
    public boolean delete(long id) {
        try {
            T t = ((Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]).newInstance();
            t.setId(id);
            return delete(t);
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    public T findById(long id) {
        Set<String> keys = null;
        try {
            keys = jedis.keys(exGenerateKeyById(id));
        } catch (Exception e) {
            return null;
        }
        if (keys == null || keys.size() <= 0) {
            return null;
        }
        T t = JSONObject.parseObject(jedis.get(keys.iterator().next()), (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]);
        return t;
    }

    /**
     * 查询全部
     *
     * @return
     */
    public List<T> findAll() {
        Set<String> keys = null;
        try {
            keys = jedis.keys(exGenerateKey(null));
        } catch (Exception e) {
            return new ArrayList<>();
        }
        if (keys == null || keys.size() <= 0) {
            return new ArrayList<>();
        }
        List<T> list = new ArrayList<>();
        for(String key:keys){
            list.add(JSONObject.parseObject(jedis.get(key), (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]));
        }
        return list;
    }
}
